#include "code_window.h"
#include "ui_code_window.h"

#include <Qsci/qsciscintilla.h>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
#include <QMessageBox>

code_window::code_window(Module_Data *data, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::code_window)
{
    ui->setupUi(this);

    setWindowTitle("Code Window");
    setAttribute(Qt::WA_ShowModal, true);   // 设置模态窗口
    setAttribute(Qt::WA_DeleteOnClose);     // 关闭窗口时触发析构函数

    this->data = data;

    this->init_Qsci();
}

code_window::~code_window()
{
    this->data->code = this->code_edit_editext->text();
    delete ui;
}

void code_window::init_Qsci()
{
    /// Code Edit
    code_edit_editext->setLexer(code_edit_textLexer);

    code_edit_editext->setMarginType(0, QsciScintilla::NumberMargin);
    code_edit_editext->setMarginLineNumbers(0, true);
    code_edit_editext->setMarginWidth(0, 30);

  //connect(code_edit_editext, &QsciScintilla::textChanged, this, &code_window::code_edit_textChanged);

    ui->gridLayout_code_edit->addWidget(code_edit_editext);

    code_edit_editext->setText(this->data->code);
    ///---------------------------------------------------------------

    /// Code View
    code_view_editext->setLexer(code_view_textLexer);

    code_view_editext->setMarginType(0, QsciScintilla::NumberMargin);
    code_view_editext->setMarginLineNumbers(0, true);
    code_view_editext->setMarginWidth(0, 30);

    code_view_editext->setReadOnly(true);   // 设置只读模式

    this->make_codeView_code();

    ui->gridLayout_code_view->addWidget(code_view_editext);



    ///---------------------------------------------------------------
}

void code_window::make_codeView_code()
{
    code_view_editext->clear();
    code_view_editext->append(make_code(this->data));
}

QString code_window::make_code(Module_Data *data)
{
    QString Code;

    // 生成 Module 头部
    Code.append(QString("module %1").arg(data->get_module_name()));

    if (data->sum_portNumber())
    {
        Code.append(QString("(\n"));

        foreach(PortAttribute p, data->ports.Input_List) {
            Code.append(QString("\t%1,\n").arg(p.name));
        }

        foreach(PortAttribute p, data->ports.Output_List) {
            Code.append(QString("\t%1,\n").arg(p.name));
        }

        foreach(PortAttribute p, data->ports.InOut_List) {
            Code.append(QString("\t%1,\n").arg(p.name));
        }

        Code.append(QString("\t)\n"));
    }
    else
    {
        Code.append(QString("()\n"));
    }

    Code.append("\n");

    // 生成 Port,遍历Port列表
    Code.append("\t// Port声明代码\n");

    foreach(PortAttribute p, data->ports.Input_List) {
        Code.append(QString("\t%1 %2 %3 %4;\n").arg(p.type.toLower(), p.datatype, make_dataSize(p.dataSize), p.name));
    }

    foreach(PortAttribute p, data->ports.Output_List) {
        Code.append(QString("\t%1 %2 %3 %4;\n").arg(p.type.toLower(), p.datatype, make_dataSize(p.dataSize), p.name));
    }

    foreach(PortAttribute p, data->ports.InOut_List) {
        Code.append(QString("\t%1 %2 %3 %4;\n").arg(p.type.toLower(), p.datatype, make_dataSize(p.dataSize), p.name));
    }

    Code.append("\n\n");

    // 生成 Module 实例化
    Code.append("\t// Module实例化代码\n");

    foreach(Child_Module_Data *child, data->child_module) {
        Code.append(QString("\t%1 %2();\n").arg(child->parent->get_module_name(), child->instantiation_name));
    }


    Code.append("\n\n");

    // 插入用户代码
    Code.append("\t// 用户代码\n");

    QStringList list = data->code.split("\n");
    foreach(QString userCode, list)
    {
        Code.append("\t" + userCode + "\n");
    }

    Code.append("\n\n");

    // 生成 Module 尾部
    Code.append("endmodule");

    return Code;
}


void code_window::on_tabWidget_currentChanged(int index)
{//切换编辑/显示界面时自动保存代码
    if (index == 1)
    {
        this->data->code = this->code_edit_editext->text();
        this->make_codeView_code();
    }

}

QString code_window::make_dataSize(int size)
{
    QString ret;

    if (size == 1 || size == 0)
        return NULL;
    else
        ret = QString("[%1:0]").arg(size - 1);
    return ret;
}

//void code_window::code_edit_textChanged()
//{
//    this->data->code = this->code_edit_editext->text();
//    qDebug() << this->data->code<<"111";
//}

